package arithmetic.thread;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author jiangfeng 2019/7/14 23:28
 */
public class DemoABA {
    //ABA问总用解快
    static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    static AtomicStampedReference<Integer> atomicstampedReference=new AtomicStampedReference<>(100,1);

    public static void main(String[] args) {
        System.out.println("==========以下是ABA问题的产生==============");
        new Thread(() -> {
            atomicReference.compareAndSet(100, 101);
            atomicReference.compareAndSet(101, 100);
        }, "t1").start();
        new Thread(() -> {
//暂1秘t2线程,保证上丽t1线程完成了一ABA操
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(atomicReference.compareAndSet(100, 2019) + "\t" + atomicReference.get());
        }, "t2").start();

        System.out.println("------------------------");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("==========以下是ABA问题的解决==============");

        new Thread(() -> {

            int stamp = atomicstampedReference.getStamp();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"\t第1次版本号："+stamp);
            atomicstampedReference.compareAndSet(100, 101,atomicstampedReference.getStamp(),atomicstampedReference.getStamp()+1);
            atomicstampedReference.compareAndSet(101, 100,atomicstampedReference.getStamp(),atomicstampedReference.getStamp()+1);
        }, "t3").start();

        new Thread(() -> {
//暂1秘t2线程,保证上丽t1线程完成了一ABA操
            int stamp = atomicstampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+"\t第1次版本号："+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean b = atomicstampedReference.compareAndSet(100, 2019, stamp, stamp + 1);
            System.out.println( Thread.currentThread().getName()+ b+"\t" + atomicstampedReference.getReference());
        }, "t4").start();


    }

    @Test
    public void test(){
        new ArrayList<>().add(2);
        new CopyOnWriteArrayList<>();
       // Collections.synchronizedList();//相当于代理模式
        //HashSet;
      //  new HashMap().put()

    }
}
